package com.simon.annual.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.simon.annual.entity.CompanyPublic;
import com.simon.annual.entity.ReportCompany;
import com.simon.annual.repositoy.ICompanyPublicRepositoy;
import com.simon.annual.repositoy.IReportCompanyRepositoy;
import com.simon.annual.service.ICompanyPublicInfo;

/**
 *第二节：公司概况 
 * */
@Service
public class FindCompanyPublicInfoImpl implements ICompanyPublicInfo{

	private final Logger log = Logger.getLogger(this.getClass());
	
	@Resource
	private ICompanyPublicRepositoy companyPublicRepositoy;
	@Resource
	private IReportCompanyRepositoy reportCompanyRepositoy;
	@Resource
	private Environment env;
	
	
	@Override
	public void analysis(Document doc, int companyPtrId) {
//		log.info(doc);
		Elements ele = doc.getElementsMatchingOwnText(env.getProperty("pdf.two"));
		Element index =null;
		if(ele.size()==2){
			index=findNextByChar(env.getProperty("pdf.two.info"), ele.last(),-1);
		}else{
			for (Element element : ele) {
				if(element.parent().tagName().equals("taggedpdf-doc")){
					Element base = findNextByChar(env.getProperty("pdf.two.info"), element,-1);
					if(base!=null){
						index = base;
						break;
					}	
				}
			}
		}
		if(index!=null){
			//基本信息
			Element ed = getNextTag(index, index);
			Elements tds = ed.select("table tr  > *");
			ReportCompany reportCompany = new ReportCompany();
			reportCompany.setNameZh(tds.get(1).text());
			int ind =-2;
			if(tds.get(2).getElementsMatchingOwnText(env.getProperty("pdf.two.en")).hasText()){
				ind =0;
				reportCompany.setNameEn(tds.get(3+ind).text());
			}
			reportCompany.setStockAbbr(tds.get(5+ind).text());
			reportCompany.setStockCode(tds.get(7+ind).text());
			reportCompany.setLegalRep(tds.get(9+ind).text());
			reportCompany.setRegAddress(tds.get(11+ind).text());
			reportCompany.setOfficeAddress(tds.get(13+ind).text());
			reportCompany.setBroker(tds.get(15+ind).text());
			reportCompany.setBrokerAddress(tds.get(17+ind).text());
			reportCompany.setCpaFirm(tds.get(19+ind).text());
			reportCompany.setCpa(tds.get(21+ind).text());
			reportCompany.setCpaAddress(tds.size()>23?tds.get(23+ind).text():"");
			//联系方式
			Element el = findNextByChar(env.getProperty("pdf.two.tel"), ed,1);
			el = getNextTag(el, el);
			Elements td = el.select("table tr  > *");
			reportCompany.setCompanySecretary(td.get(1).text());
			reportCompany.setPhoneNo(td.get(3).text());
			reportCompany.setFaxNo(td.get(5).text());
			reportCompany.setEmailAddress(td.get(7).text());
			reportCompany.setWebsiteAddress(td.get(9).text());
			reportCompany.setContactAddress(td.get(11).text());
			reportCompany.setDisclosureWebsite(td.get(13).text());
			reportCompany.setLocationOfAnnualReport(td.size()>15?td.get(15).text():"");
			//企业信息
			Element com = findNextByChar(env.getProperty("pdf.two.xx.title"), ed,-20);
			com = getNextTag(com, com);
			com = buildMeet(com);
			Elements comTds = com.select("table tr > *");
			reportCompany.setListMarket(comTds.get(1).text());
			reportCompany.setListDate(comTds.get(3).text());
			reportCompany.setMarketSubtype(comTds.get(5).text());
			reportCompany.setIndustry(comTds.get(7).text());
			reportCompany.setMainProduct(comTds.size()>9?comTds.get(9).text():"");
			reportCompany.setTradeType(comTds.size()>11?comTds.get(11).text():"");
			reportCompany.setCapitalization(comTds.size()>13?comTds.get(13).text():"");
			reportCompany.setMarketMakerNo(comTds.size()>15?comTds.get(15).text():"");
			reportCompany.setControllingStake(comTds.size()>17?comTds.get(17).text():"");
			reportCompany.setActualController(comTds.size()>19?comTds.get(19).text():"");
			//注册信息
			Element reg = findNextByChar(env.getProperty("pdf.two.reg"), ed,-30);
			if(reg!=null){
				reg =getNextTag(reg, reg);
				Elements regTd = reg.select("table tr > *");
				int i =0;
				if(regTd.size()==9||regTd.size()==3){
					i=-3;
				}
				if(regTd.size()>=3){
					reportCompany.setRegCode(regTd.get(4+i).text());
					reportCompany.setIsRegCodeChanged(regTd.get(5+i).text());
					reportCompany.setTaxCode(regTd.size()>7+i?regTd.get(7+i).text():"");
					reportCompany.setIsTaxCodeChanged(regTd.size()>8+i?regTd.get(8+i).text():"");
					reportCompany.setOrgCode(regTd.size()>10+i?regTd.get(10+i).text():"");
					reportCompany.setIsOrgCodeChanged(regTd.size()>11+i?regTd.get(11+i).text():"");
					reportCompany.setProjectScopeId(companyPtrId);
				}
			}
			reportCompanyRepositoy.save(reportCompany);
		}
	}
	
	
	@Override
	public int getCompanyPtrId(Document doc) {
		List<CompanyPublic> companyPublicList = companyPublicRepositoy.findByStockCode(getNeeqCode(doc));
		return companyPublicList.get(0).getCompanyPtrId();
	}

	@Override
	public Document init(String path) {
		try {
			Document doc = Jsoup.parse(new File(path),"UTF-8");
			String html = doc.html();
//			Jsoup.clean(html, Whitelist.relaxed());
			//<sect>
			html = html.replaceAll("<sect(.*)>", "").replaceAll("</sect>", "");
			//<part>
			html = html.replaceAll("<part(.*)>", "").replaceAll("</part>", "");
			//<Document>
			html = html.replaceAll("<document(.*)>", "").replaceAll("</document>", "");
			//<Lbl>
//			html = html.replaceAll("<lbl(.*)>", "<lbody>").replaceAll("</lbl>", "</lbody>");
			//<LBody>
			html = html.replaceAll("<lbody(.*)>", "<td>").replaceAll("</lbody>", "</td>");
			//<LI>
			html = html.replaceAll("<li(.*)>", "<tr>").replaceAll("</li>", "</tr>");
			//<L>
			html = html.replaceAll("<l(.*)>", "<table>").replaceAll("</l>", "</table>");
			//<div>
			html = html.replaceAll("<div(.*)>", "").replaceAll("</div>", "");
			//<Textbox>
			html = html.replaceAll("<textbox(.*)>", "").replaceAll("</textbox>", "");
			//
			html = html.replaceAll("<table(.*)>+\n+<table(.*)>", "<table>").replaceAll("</table>+\n</table>+", "</table>");
			//thead
			html = html.replaceAll("<thead(.*)>", "<tbody>").replaceAll("</thead>", "</tbody>");
			
//			html = html.replaceAll("figure", "p");
			
			//<P>2015年度报告</P>
//			html = html.replaceAll(env.getProperty("pdf.year.report"), "");
			//<p>公告编号(.*)</p>
//			html = html.replaceAll(env.getProperty("pdf.report.no"), "");
			doc = Jsoup.parse(html);
			return cleanDom(doc);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	private Document cleanDom(Document doc) {
		Elements  Ap = doc.select("p");
		for (Element element : Ap) {
			if(!element.hasText()
					||(element.parent().tagName().contains("taggedpdf-doc")
							&&StringUtil.isNumeric(element.text().replace("-", "")))){
				element.remove();
			}
		}
		//toc
//		doc.select("toc").remove();
//		ImageData
		doc.select("imagedata").remove();
		//Figure
//		doc.select("figure");
		for (Element element : doc.select("figure")) {
			if(!element.hasText()){
				element.remove();
			}
		}
//		Elements table = doc.select("table");
//		for (Element element : table) {
//			element.children().size();
//		}
		doc.select("artifact").remove();
		for (Element element : doc.getElementsMatchingOwnText(env.getProperty("pdf.page"))) {
			if(element.parent().tagName().contains("taggedpdf-doc")){
				element.remove();
			}
		}
		for (Element element : doc.getElementsMatchingOwnText(env.getProperty("pdf.report.no"))) {
			if(element.parent().tagName().contains("taggedpdf-doc")){
				element.remove();
			}
		}
		for (Element element : doc.getElementsMatchingOwnText(env.getProperty("pdf.year.report"))) {
			if(element.text().indexOf(env.getProperty("pdf.year.report.str"))+env.getProperty("pdf.year.report.str").length()==element.text().length()){
				element.remove();
			}
		}
		return doc;
	}
	
	/**
	 * 获取股票代码
	 * */
	public String getNeeqCode(Document doc){
		Elements neeq = doc.getElementsMatchingOwnText(env.getProperty("pdf.companyPtrId"));
		if(!neeq.hasText()){
			Element neeqE = doc.select("p:contains(NEEQ)").first();
			return neeqE.text().replaceAll("\\D+", "");
		}
		for (Element ele : neeq) {
			if(ele.text().length()<5){
				Element pa = ele.parent();
				if(!pa.tagName().equals("tr")){
					pa = pa.parent();
					ele = ele.parent();
				}
				if(pa.tagName().equals("tr")&&pa.parent().parent().tagName().equals("table")
						&&pa.children().size()==2){
					return ele.nextElementSibling().text();
				}
			}
		}
		return null;
	}
	
	
	/**
	 *合并跨页表格
	 * */
	@Override
	public Element getNextTag(Element e, Element newElement) {
		Element tag = e.nextElementSibling();
		if(tag!=null&&tag.tagName().equals("table")){
			//判断合并的结构是否一致 不一致则不属于合并范围
//			if(newElement.select("table tr").last().children().size()!=tag.select("table tr").first().children().size()){
//				return newElement;
//			}
//			tag.
			newElement = newElement.append(tag.html());
			Element nexttag = newElement;
			tag.remove();
			return getNextTag(nexttag,newElement);
		}else{
			Elements tbodys = newElement.select("tbody");
			for (int i = 0; i < tbodys.size(); i++) {
				if(!tbodys.get(i).hasText()||tbodys.get(i).select("tr").isEmpty()){
					tbodys.remove(tbodys.get(i));
					i--;
				}
			}
			//合并分页table
			if(tbodys.size()>1){
				for (int i = 0; i < tbodys.size()-1; i++) {
					Element body = tbodys.get(i+1);
					Elements  element = body.select("tr");
					if(!element.isEmpty()){
						boolean ps = element.first().children().size()==tbodys.get(i).select("tr").last().children().size();
						if(ps&&!tbodys.get(i).select("tr").last().children().first().hasText()){
							Elements eTd = element.first().children();
							for (int j = 0; j < eTd.size(); j++) {
								tbodys.get(i).select("tr").last().child(j).appendText(eTd.get(j).text());
							}
							element.first().remove();
							if(!tbodys.get(i+1).hasText()){
								tbodys.remove(i+1);
							}
						}
					}
				}
			}
			return newElement;
		}
	}

	/**
	 * 查找当前节点下一个同级节点
	 * */
	@Override
	public Element findNextTag(String tag,Element e){
		Element next = e.nextElementSibling();
		//获取非同级元素
//		boolean hasTable = next.children().select("table").size()>0;
//		next = hasTable?next.select("table").first():next;
		if(next.tagName().equals("table")){//合并table
			next = getNextTag(next,next);
		}
		boolean s = next.tagName().equals(tag);
//		next = hasTable?next.parent():next;
		return s?next:findNextTag(tag,next);
	}
	/**
	 * 查找当前节点下一个第N个同级节点
	 * */
	@Override
	public Element findNextTag(String tag,Element e,int n){
		Element ne =e;
		for (int i = 1; i <= n; i++) {
			 ne = findNextTag(tag,ne);
		}
		return ne;
	}

	/**
	 * 查找当前节点下一个同级节点
	 * */
	@Override
	public Element findNextTagNoMer(Element newElement,Element e){
		Element tag = e.nextElementSibling();
		if(tag!=null&&tag.tagName().equals("table")){
			newElement = newElement.append(tag.html());
			Element nexttag = newElement;
			tag.remove();
			return findNextTagNoMer(nexttag,newElement);
		}
		return e;
	}
	
	@Override
	public Element buildTable(Element e){
		Elements els = e.select("tr");
		for (int i = 1; i < els.size(); i++) {
			if(els.get(i).children().size()!=els.first().children().size()){
				els.get(i-1).children().last().appendText(els.get(i).text());
				els.get(i).remove();
			}
		}
		return e;
	}

	@Override
	public Element findNextByChar(String chars, Element e ,int index) {
		if(e.getElementsMatchingOwnText(chars).hasText()){
			return e;
		}
		Element next = e.nextElementSibling();
		index++;
		if(index>5||next==null){
			return null;
		}
		boolean s = next.getElementsMatchingOwnText(chars).hasText();
		return s?next:findNextByChar(chars,next,index);
	}
	
	@Override
	public Element findNextByCharEndChar(String chars,String end, Element e ,int index) {
		if(e.getElementsMatchingOwnText(chars).hasText()){
			return e;
		}
		Element next = e.nextElementSibling();
		index++;
		if(index>5||next==null||next.getElementsMatchingOwnText(end).hasText()){
			return null;
		}
		boolean s = next.getElementsMatchingOwnText(chars).hasText();
		return s?next:findNextByCharEndChar(chars,end,next,index);
	}
	
	@Override
	public Element findEndByChar(String end,Element e,String result ,int i) {
		i +=1;
		if(e==null){
			return null;
		}
		if(e.getElementsMatchingOwnText(end).hasText()){
			return e;
		}
		Element next = e.nextElementSibling();
		boolean s = next.getElementsMatchingOwnText(end).hasText();
		if(s){
			return Jsoup.parse(result);
		}
		result +=next.html();
		//设置阀值防止栈溢出
		if(!s&&i>150){
			return null;
		}
		return s?next:findEndByChar(end,next,result,i);
	}


	@Override
	public Element getParentTag(Element pe, Element e) {
		// TODO Auto-generated method stub
		pe =e.parent();
		return pe.tagName().contains("taggedpdf-doc")?e:getParentTag(pe,pe);
	}
	
	/**
	 * 合并table换行
	 * */
	private Element buildMeet(Element newElement){
		Elements tbodys = newElement.select("tbody");
		//合并分页table
		if(tbodys.size()>0){
			for (int i = 0; i < tbodys.size()-1; i++) {
				Element body = tbodys.get(i+1);
				//去除多余的合并内容
				if(body.getElementsMatchingOwnText(env.getProperty("pdf.two")).hasText()){
					while(i+1<tbodys.size()){
						tbodys.get(i+1).remove();
						i++;
					}
					return newElement;
				}
				Elements  element = body.select("tr");
				if(!element.isEmpty()){
					boolean ps = element.first().children().size()==tbodys.get(i).select("tr").last().children().size();
					if(ps&&!body.select("tr").first().children().first().hasText()){
						Elements eTd = element.first().children();
						for (int j = 0; j < eTd.size(); j++) {
							tbodys.get(i).select("tr").last().child(j).appendText(eTd.get(j).text());
						}
						element.first().remove();
						if(!tbodys.get(i+1).hasText()){
							tbodys.remove(i+1);
						}
					}
				}
			}
		}
		return newElement;
	}
}
